package es.uc3m.setichat.utils;

import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CipherMessage {
	
	private PrivateKey privateKey;
	private PublicKey publicKey;
	
	public PrivateKey getPrivateKey() {
		return privateKey;
	}

	public PublicKey getPublicKey() {
		return publicKey;
	}

	public void setPrivateKey(PrivateKey privateKey){
		this.privateKey=privateKey;
	}
	
	public void setPublicKey(PublicKey publicKey){
		this.publicKey=publicKey;
	}
		
	public String encrypted(String message){
		try {
			GenerateKeyIV generateKeyIV= new GenerateKeyIV();
			generateKeyIV.generateIV();
			generateKeyIV.generateKey();
			
			Cipher SymKeyCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			SecretKeySpec aesKeySpec = new SecretKeySpec(generateKeyIV.getKey(), "AES");
			SymKeyCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec, new IvParameterSpec(generateKeyIV.getIV()));
			byte encryptedMessage[] = SymKeyCipher.doFinal(message.getBytes("UTF-8"));
			
			Cipher publicKeyCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
			publicKeyCipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
			
			byte encryptedKey[] = publicKeyCipher.doFinal(generateKeyIV.getKey());
			
			byte messageToSend[] = new byte[encryptedKey.length + generateKeyIV.getIV().length + encryptedMessage.length];
			System.arraycopy(encryptedKey, 0, messageToSend, 0, encryptedKey.length);
			System.arraycopy(generateKeyIV.getIV(), 0, messageToSend, encryptedKey.length, 16);
			System.arraycopy(encryptedMessage, 0, messageToSend, (encryptedKey.length+generateKeyIV.getIV().length), encryptedMessage.length);

			
			return Base64.encodeToString(messageToSend, false);
						
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "";
	}
	
	public String decrypted(String message){
		byte 	messages[] 	= Base64.decode(message),
				iv[] 				= new byte[16],
				encryptedKey[] 		= new byte[64],
				encryptedMessage[]	= new byte[messages.length - iv.length - encryptedKey.length];
		
		System.arraycopy(messages, 0,  encryptedKey, 0, encryptedKey.length);
		System.arraycopy(messages, encryptedKey.length, iv, 0, iv.length);
		System.arraycopy(messages, (encryptedKey.length+iv.length), encryptedMessage, 0, encryptedMessage.length);
				
		try {
			
			Cipher publicKeyCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
			publicKeyCipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
			byte aesKey[] = publicKeyCipher.doFinal(encryptedKey);
			 		
			Cipher SymKeyCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey, "AES");
			SymKeyCipher.init(Cipher.DECRYPT_MODE, aesKeySpec, new IvParameterSpec(iv));
			byte decryptedMessage[] = SymKeyCipher.doFinal(encryptedMessage);
			
			return new String(decryptedMessage);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "";
	} 
	
}
